package ConnectivityEditor.Connectivity;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import Builder.MainCamera;
import Command.LDrawPart;
import Common.Box3;
import Common.Ray3;
import Common.Vector3f;
import Connectivity.CollisionBox;
import Connectivity.Connectivity;
import Connectivity.Hole;
import Connectivity.IConnectivity;
import Connectivity.ICustom2DField;
import Connectivity.MatrixItem;
import ConnectivityEditor.Window.ConnectivityEditor;
import ConnectivityEditor.Window.DefaultConnectivityRenderer;
import ConnectivityEditor.Window.IConnectivityRenderer;
import LDraw.Support.MatrixMath;
public class ConnectivityRendererForConnectivityEditor {
public MainCamera camera;
private GLU glu;
public ConnectivityRendererForConnectivityEditor(MainCamera cam) {
glu = new GLU();
camera = cam;
}
public void draw(GL2 gl2) {
gl2.glDisable(GL2.GL_LIGHTING);
gl2.glUseProgram(0);
gl2.glMatrixMode(GL2.GL_PROJECTION);
gl2.glPushMatrix();
gl2.glLoadMatrixf(camera.getProjection(), 0);
gl2.glMatrixMode(GL2.GL_MODELVIEW);
gl2.glPushMatrix();
gl2.glLoadMatrixf(camera.getModelView(), 0);
drawConnectivity(gl2);
drawCollisionBoxes(gl2);
drawBoundingBoxes(gl2);
gl2.glMatrixMode(GL2.GL_MODELVIEW);
gl2.glPopMatrix();
gl2.glMatrixMode(GL2.GL_PROJECTION);
gl2.glPopMatrix();
gl2.glEnable(GL2.GL_LIGHTING);
}
public void drawCollisionBox(GL2 gl2, Vector3f[] pos) {
gl2.glBegin(GL2.GL_QUADS); // draw using triangles
gl2.glVertex3f(pos[0].x, pos[0].y, pos[0].z);
gl2.glVertex3f(pos[1].x, pos[1].y, pos[1].z);
gl2.glVertex3f(pos[2].x, pos[2].y, pos[2].z);
gl2.glVertex3f(pos[3].x, pos[3].y, pos[3].z);
gl2.glVertex3f(pos[7].x, pos[7].y, pos[7].z);
gl2.glVertex3f(pos[6].x, pos[6].y, pos[6].z);
gl2.glVertex3f(pos[5].x, pos[5].y, pos[5].z);
gl2.glVertex3f(pos[4].x, pos[4].y, pos[4].z);
gl2.glVertex3f(pos[0].x, pos[0].y, pos[0].z);
gl2.glVertex3f(pos[4].x, pos[4].y, pos[4].z);
gl2.glVertex3f(pos[5].x, pos[5].y, pos[5].z);
gl2.glVertex3f(pos[1].x, pos[1].y, pos[1].z);
gl2.glVertex3f(pos[6].x, pos[6].y, pos[6].z);
gl2.glVertex3f(pos[2].x, pos[2].y, pos[2].z);
gl2.glVertex3f(pos[1].x, pos[1].y, pos[1].z);
gl2.glVertex3f(pos[5].x, pos[5].y, pos[5].z);
gl2.glVertex3f(pos[6].x, pos[6].y, pos[6].z);
gl2.glVertex3f(pos[2].x, pos[2].y, pos[2].z);
gl2.glVertex3f(pos[3].x, pos[3].y, pos[3].z);
gl2.glVertex3f(pos[7].x, pos[7].y, pos[7].z);
gl2.glVertex3f(pos[7].x, pos[7].y, pos[7].z);
gl2.glVertex3f(pos[3].x, pos[3].y, pos[3].z);
gl2.glVertex3f(pos[0].x, pos[0].y, pos[0].z);
gl2.glVertex3f(pos[4].x, pos[4].y, pos[4].z);
gl2.glEnd();
}
private void drawBoundingBox(GL2 gl2, Vector3f[] pos) {
gl2.glBegin(GL2.GL_LINES); // draw using triangles
gl2.glColor4d(1, 0, 0, 1.0f);
gl2.glVertex3f(pos[0].x, pos[0].y, pos[0].z);
gl2.glVertex3f(pos[1].x, pos[1].y, pos[1].z);
gl2.glVertex3f(pos[1].x, pos[1].y, pos[1].z);
gl2.glVertex3f(pos[2].x, pos[2].y, pos[2].z);
gl2.glVertex3f(pos[2].x, pos[2].y, pos[2].z);
gl2.glVertex3f(pos[3].x, pos[3].y, pos[3].z);
gl2.glVertex3f(pos[3].x, pos[3].y, pos[3].z);
gl2.glVertex3f(pos[0].x, pos[0].y, pos[0].z);
gl2.glVertex3f(pos[4].x, pos[4].y, pos[4].z);
gl2.glVertex3f(pos[5].x, pos[5].y, pos[5].z);
gl2.glVertex3f(pos[5].x, pos[5].y, pos[5].z);
gl2.glVertex3f(pos[6].x, pos[6].y, pos[6].z);
gl2.glVertex3f(pos[6].x, pos[6].y, pos[6].z);
gl2.glVertex3f(pos[7].x, pos[7].y, pos[7].z);
gl2.glVertex3f(pos[7].x, pos[7].y, pos[7].z);
gl2.glVertex3f(pos[4].x, pos[4].y, pos[4].z);
gl2.glVertex3f(pos[0].x, pos[0].y, pos[0].z);
gl2.glVertex3f(pos[4].x, pos[4].y, pos[4].z);
gl2.glVertex3f(pos[1].x, pos[1].y, pos[1].z);
gl2.glVertex3f(pos[5].x, pos[5].y, pos[5].z);
gl2.glVertex3f(pos[2].x, pos[2].y, pos[2].z);
gl2.glVertex3f(pos[6].x, pos[6].y, pos[6].z);
gl2.glVertex3f(pos[3].x, pos[3].y, pos[3].z);
gl2.glVertex3f(pos[7].x, pos[7].y, pos[7].z);
gl2.glEnd();
}
private void drawCollisionBoxes(GL2 gl2) {
gl2.glLoadMatrixf(camera.getModelView(), 0);
LDrawPart part = ConnectivityEditor.getInstance().getWorkingPart();
if (part == null)
return;
ArrayList<CollisionBox> boxes = part.getCollisionBoxList();
if (boxes == null || boxes.size() == 0)
return;
for (int j = 0; j < boxes.size(); j++) {
CollisionBox collisionBox = boxes.get(j);
if (collisionBox.isSelected()) {
gl2.glColor4d(0, 0, 0, 0.3f);
} else {
gl2.glColor4d(0, 1, 0, 0.3f);
}
Vector3f[] boxPos = new Vector3f[8];
boxPos[0] = new Vector3f(-collisionBox.getsX(),
-collisionBox.getsY(), -collisionBox.getsZ());
boxPos[1] = new Vector3f(collisionBox.getsX(),
-collisionBox.getsY(), -collisionBox.getsZ());
boxPos[2] = new Vector3f(collisionBox.getsX(),
-collisionBox.getsY(), collisionBox.getsZ());
boxPos[3] = new Vector3f(-collisionBox.getsX(),
-collisionBox.getsY(), collisionBox.getsZ());
boxPos[4] = new Vector3f(-collisionBox.getsX(),
collisionBox.getsY(), -collisionBox.getsZ());
boxPos[5] = new Vector3f(collisionBox.getsX(),
collisionBox.getsY(), -collisionBox.getsZ());
boxPos[6] = new Vector3f(collisionBox.getsX(),
collisionBox.getsY(), collisionBox.getsZ());
boxPos[7] = new Vector3f(-collisionBox.getsX(),
collisionBox.getsY(), collisionBox.getsZ());
for (int k = 0; k < 8; k++) {
boxPos[k] = collisionBox.getTransformMatrix().transformPoint(
boxPos[k]);
boxPos[k] = part.transformationMatrix().transformPoint(
boxPos[k]);
}
drawCollisionBox(gl2, boxPos);
}
}
private void drawBoundingBoxes(GL2 gl2) {
gl2.glLoadMatrixf(camera.getModelView(), 0);
LDrawPart part = ConnectivityEditor.getInstance().getWorkingPart();
if (part == null)
return;
Box3 boundingBox = part.boundingBox3();
if (boundingBox != null) {
Vector3f max = boundingBox.getMax();
Vector3f min = boundingBox.getMin();
Vector3f[] boxPos = new Vector3f[8];
boxPos[0] = new Vector3f(min.x, min.y, min.z);
boxPos[1] = new Vector3f(max.x, min.y, min.z);
boxPos[2] = new Vector3f(max.x, min.y, max.z);
boxPos[3] = new Vector3f(min.x, min.y, max.z);
boxPos[4] = new Vector3f(min.x, max.y, min.z);
boxPos[5] = new Vector3f(max.x, max.y, min.z);
boxPos[6] = new Vector3f(max.x, max.y, max.z);
boxPos[7] = new Vector3f(min.x, max.y, max.z);
drawBoundingBox(gl2, boxPos);
}
}
private void drawConnectivity(GL2 gl2) {
LDrawPart part = ConnectivityEditor.getInstance().getWorkingPart();
if (part == null)
return;
if (part.getConnectivityList() == null)
return;
ArrayList<Connectivity> copy = new ArrayList<Connectivity>(
part.getConnectivityList());
for (Connectivity conn : copy) {
conn.updateConnectivityOrientationInfo();
// if (conn instanceof ICustom2DField) {
// drawCustom2DField(gl2, conn);
// } else
drawConnectivity(gl2, conn);
}
}
private void drawCustom2DField(GL2 gl2, Connectivity conn) {
MatrixItem[][] matrixItmes = ((ICustom2DField) conn).getMatrixItem();
if (conn instanceof Hole) {
for (int column = 0; column < matrixItmes.length; column++)
for (int row = 0; row < matrixItmes[column].length; row++) {
matrixItmes[column][row]
.updateConnectivityOrientationInfo();
drawHoleMatrix(gl2, matrixItmes[column][row]);
}
} else {
for (int column = 0; column < matrixItmes.length; column++)
for (int row = 0; row < matrixItmes[column].length; row++) {
matrixItmes[column][row]
.updateConnectivityOrientationInfo();
drawStudMatrix(gl2, matrixItmes[column][row]);
}
}
}
private HashMap<Connectivity, IConnectivityRenderer> rendererMap;
public void drawConnectivity(GL2 gl2, Connectivity conn) {
if (rendererMap == null)
rendererMap = new HashMap<Connectivity, IConnectivityRenderer>();
if (rendererMap.containsKey(conn) == false)
rendererMap
.put(conn, DefaultConnectivityRenderer.createRendererFor(
camera, conn));
rendererMap.get(conn).draw(gl2);
}
public void drawStudMatrix(GL2 gl2, MatrixItem matrixItem) {
gl2.glColor3d(1, matrixItem.getAltitude() / 29.0,
matrixItem.getAltitude() / 29.0);
if (matrixItem.getParent().isSelected())
gl2.glColor3d(0, 0, 0);
Vector3f pos = matrixItem.getCurrentPos();
// pos = LDrawGridTypeT.getSnappedPos(pos, LDrawGridTypeT.Medium);
GLUquadric earth = glu.gluNewQuadric();
glu.gluQuadricDrawStyle(earth, GLU.GLU_FILL);
glu.gluQuadricNormals(earth, GLU.GLU_FLAT);
glu.gluQuadricOrientation(earth, GLU.GLU_OUTSIDE);
final float radius = 2;
final int slices = 4;
final int stacks = 4;
gl2.glLoadMatrixf(camera.getModelView(), 0);
gl2.glTranslatef(pos.getX(), pos.getY(), pos.getZ());
glu.gluSphere(earth, radius, slices, stacks);
glu.gluDeleteQuadric(earth);
}
public void drawHoleMatrix(GL2 gl2, MatrixItem matrixItem) {
gl2.glColor3d(matrixItem.getAltitude() / 29.0, 1,
matrixItem.getAltitude() / 29.0);
if (matrixItem.getParent().isSelected())
gl2.glColor3d(0, 0, 0);
Vector3f pos = matrixItem.getCurrentPos();
// pos = LDrawGridTypeT.getSnappedPos(pos, LDrawGridTypeT.Medium);
// Draw sphere (possible styles: FILL, LINE, POINT).
GLUquadric earth = glu.gluNewQuadric();
glu.gluQuadricDrawStyle(earth, GLU.GLU_FILL);
glu.gluQuadricNormals(earth, GLU.GLU_FLAT);
glu.gluQuadricOrientation(earth, GLU.GLU_OUTSIDE);
final float radius = 2;
final int slices = 4;
final int stacks = 4;
gl2.glLoadMatrixf(camera.getModelView(), 0);
gl2.glTranslatef(pos.getX(), pos.getY(), pos.getZ());
glu.gluSphere(earth, radius, slices, stacks);
glu.gluDeleteQuadric(earth);
}
public IConnectivity getHittedConnectivity(MainCamera camera,
float screenX, float screenY) {
FloatBuffer distance = FloatBuffer.allocate(1);
distance.put(0, Float.MAX_VALUE);
FloatBuffer distanceTemp = FloatBuffer.allocate(1);
IConnectivity hittedConn = null;
LDrawPart part = ConnectivityEditor.getInstance().getWorkingPart();
if (part == null)
return null;
if (rendererMap == null)
return null;
for (Connectivity conn : part.getConnectivityList()) {
if (rendererMap.containsKey(conn)) {
distanceTemp.put(0, Float.MAX_VALUE);
IConnectivityRenderer renderer = rendererMap.get(conn);
if (renderer.isHitted(camera, screenX, screenY, distanceTemp)){
if (distanceTemp.get(0) < distance.get(0)) {
hittedConn = renderer.getConnectivity();
distance.put(0, distanceTemp.get(0));
}
}
}
}
return hittedConn;
}
public Vector3f getHittedPos(MainCamera camera, float screenX, float screenY) {
FloatBuffer distance = FloatBuffer.allocate(1);
distance.put(0, Float.MAX_VALUE);
FloatBuffer distanceTemp = FloatBuffer.allocate(1);
distanceTemp.put(0, Float.MAX_VALUE);
Vector3f hitPos = null;
LDrawPart part = ConnectivityEditor.getInstance().getWorkingPart();
if (part == null)
return null;
if (rendererMap == null)
return null;
Ray3 ray = camera.getRay(screenX, screenY);
for (Connectivity conn : part.getConnectivityList())
if (rendererMap.containsKey(conn)) {
IConnectivityRenderer renderer = rendererMap.get(conn);
if (renderer.isHitted(camera, screenX, screenY, distanceTemp)
&& distanceTemp.get(0) < distance.get(0)) {
distance.put(0, distanceTemp.get(0));
hitPos = ray.getOrigin().add(
ray.getDirection().scale(distance.get(0)));
}
}
return hitPos;
}
}